Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom cache provider #1017

Merged
merged 19 commits into from
May 2, 2021
Merged

Custom cache provider #1017

merged 19 commits into from
May 2, 2021

Conversation

huozhi
Copy link
Member

@huozhi huozhi commented Mar 7, 2021

Changes

This PR is a early phase implementation for #728 . Add cache property as a cache provider to SWR context

import { createCache } from 'swr'

const customCache = new Map()
const { cache } = createCache(customCache)

<SWRConfig value={{ cache }}>
   <Section />
<SWRConfig>

This is the early support of #16 , user can have a way to access the cache state and changes ( #630 ), but won't effect swr internal cache. For example, you can use any store like localStorage / RN AsyncStorage, swr internal will still use a sync cache to guarantee the correct state updating sequence.

In the long term, we can consider to deprecate the exposed cache

Example

import { createCache } from 'swr'

const localStorageCache = {
   set(key, value) {
      window.localStorage.setItem(key, JSON.stringify(value))
   },
   delete(key) {
    window.localStorage.removeItem(key)
  },
}

const { cache } = createCache(localStorageCache)

return <SWRConfig value={{ cache }}>

@codesandbox-ci
Copy link

codesandbox-ci bot commented Mar 7, 2021

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit e8c21fa:

Sandbox Source
SWR-Basic Configuration
SWR-States Configuration
SWR-Infinite Configuration
SWR-SSR Configuration

@huozhi huozhi force-pushed the custom-cache branch 2 times, most recently from 9f68e6d to 5395cd2 Compare March 8, 2021 13:26
@bionicles
Copy link

bionicles commented Mar 8, 2021

Might it be better to use the Cache API? it persists the data to apps installed locally on mobile devices, and it works inside WebWorkers https://developer.mozilla.org/en-US/docs/Web/API/Cache

https://caniuse.com/?search=cache

also, what about customizing the "get" in addition to the "set" ?

usage examples in readme would be helpful to adopt this

Copy link
Member

@shuding shuding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally LGTM! 👍

Since this is breaking and deprecates Cache, we need to first prepare a PR to add @deprecates to Cache for 0.x versions.

Secondly since we don't need to expose Cache anymore, I think we shouldn't wrap the provider with a class. We can just use a couple of lightweight functions:

function get(provider, key) { return provider.get(key) }
function set(provider, key, value) { return provider.set(key, value) }

And we don't need those internal listeners too. This change will be useful when we pass the provider down via context, and we don't maintain the cache singleton itself inside SWR.

@huozhi huozhi requested a review from shuding March 16, 2021 16:43
@huozhi
Copy link
Member Author

huozhi commented Mar 16, 2021

5834b59 latest change:

limit cache API usage inside swr, only using set/get/delete, and they're all sync APIs.

for global mutate and trigger, use const cache = globalCache to consume global cache directly;
for useSWR hook, it will consume provider from context or fallback to global cache.

@huozhi huozhi marked this pull request as ready for review March 16, 2021 16:50
@shuding
Copy link
Member

shuding commented Apr 4, 2021

I refactored the API a little bit:

const { cache, mutate } = createCache(provider)

But the implementation is still not ideal:

  • The interface of provider. Should we do serialization inside or assume it's always a string?
  • The internal code structure. use-swr depends on use-args, use-args depends on the default config and cache, but the default cache depends on use-swr. So I had to choose a strange way to implement this (defaultCache = getCacheFactory(() => {})(new Map()).cache).

I need to spend some more time thinking about it. I also moved web presets out of the default config object, because these can not be options. But I'm not very sure about that decision, let me know what you think!

@shuding shuding changed the title Custom Cache (Experimental) Custom cache provider Apr 5, 2021
@shuding
Copy link
Member

shuding commented Apr 5, 2021

While the main goal of this PR is to better cover testing scenarios, there're still a couple of to-dos left (no blocking this PR to be merged, just writing them down):

  • Add a test case for multi-level cache + mutation
  • Add a test case for multi-cache isolation (2 components with different cache provider)
  • Need to make sure that cache doesn't change. Maybe by adding a useEffect to show a warning inside useArgs...? This needs to be done when we have dev/prod separated builds, so prod can strip many unnecessary things out such as useDebugValue.

Copy link
Member Author

@huozhi huozhi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shuding new changes genterally LGTM! you might also want to fix those lint warnings.

src/types.ts Show resolved Hide resolved
src/use-swr.ts Show resolved Hide resolved
@shuding shuding added this to the 1.0 milestone Apr 13, 2021
@shuding shuding mentioned this pull request Apr 13, 2021
src/use-swr.ts Outdated Show resolved Hide resolved
Copy link
Member

@shuding shuding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉🎉🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants